#pragma once
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>

template<class T>
struct Array{
    const T & Ref;
    Array(const T & arr) : Ref(arr){}
};
template<class T>
struct Mat{
    const T & Ref;
    Mat(const T & mat) : Ref(mat){}
};

class VOut{
public:
    virtual std::string str() {return "";}
};

template<class ostream_t>
class OStream : public VOut {
public:
    ostream_t out;
    ostream_t *po;
    OStream() { po = &out; }
    OStream(ostream_t o) : out(o){ po = &out; }
    OStream(ostream_t * o) : po(o){}
    OStream& operator<<(const char*t){(*po)<<t; return *this;}
    template<class T> OStream& operator<<(const T&t){(*po)<< t; return *this;}
    template<class T> OStream& operator<<(const T*t){(*po)<<*t; return *this;}
    template<class T> OStream& operator<<(const std::vector<T> &v){
        if(v.empty()) return *this;
        return Out(v.begin(), v.end());
    }
    template<class T> OStream&operator<<(const std::list<T> &v){
        if(v.empty()) return *this;
        return Out(v.begin(), v.end());
    }
    template<class T> OStream&operator<<(const Array<T> &v){
        if(!std::size(v.Ref)) return *this;
        return Out(std::begin(v.Ref), std::end(v.Ref));
    }
    template<class T> OStream&operator<<(const Mat<T> &m){
        for(auto & v : m.Ref)
            (*this) << v << "\n";
        return *this;
    }
    template<class T> OStream& operator<<(const std::set<T> &v){
        if(v.empty()) return *this;
        return Out(v.begin(), v.end());
    }
    template<class T> OStream& operator<<(const std::unordered_set<T> &v){
        if(v.empty()) return *this;
        return Out(v.begin(), v.end());
    }
    template<class T, class Compare> OStream& operator<<(const std::multiset<T,Compare> &v){
        if(v.empty()) return *this;
        return Out(v.begin(), v.end());
    }
    template<class K, class V> OStream& operator<<(const std::pair<K,V> & pair){
        (*this) << pair.first;
        (*po) << '=';
        (*this) << pair.second;
        return *this;
    }
    template<class K, class V> OStream&operator<<(const std::unordered_map<K,V> &m){
        if(m.empty()) return *this;
        return Out(m.begin(), m.end());
    }
    template<class K, class V> OStream&operator<<(const std::map<K,V> &m){
        if(m.empty()) return *this;
        return Out(m.begin(), m.end());
    }
    template<class iterator>
    OStream& Out(iterator src, iterator dst){
        auto p = src;
        if(p != dst)   {(*po)<< '['; (*this)<<*p;}
        while(++p!=dst){(*po)<<", "; (*this)<<*p;}
        if(p != src)   (*po)<< ']';
        return *this;
    }
};

class StrStream : public OStream<std::stringstream>
{
public:
    virtual std::string str() override{
        return out.str();
    }
};

template<class ...Any>
inline void print_any(const Any ...any){
    StrStream ss;
    std::initializer_list<bool>{(ss << any, true)...}.size();
    std::cout << ss.str();
}
